`
https://leetcode.cn/problems/insert-delete-getrandom-o1/
`

class RandomizedSet {
  constructor() {
      this.arr = []
      this.valToIndex = new Map()
  }

  insert(val) {
      // 如果已经有 val 了，不用插入
      if (this.valToIndex.has(val)) {
          return false
      }

      // 插入新值
      this.arr.push(val)
      this.valToIndex.set(val, this.arr.length - 1)
      return true
  }

  remove(val) {
      // 如果没有 val 则返回 false
      if (!this.valToIndex.has(val)) {
          return false
      }
      // 获取 val 对应的索引
      const idx = this.valToIndex.get(val)
      // 如果 val 就在 arr 最后面，直接删除即可
      if (idx === this.arr.length - 1) {
          this.arr.pop()
          this.valToIndex.delete(val)
          return true
      }
      // 如果在中间，则与最后的元素交换后再删除
      const lastEl = this.arr[this.arr.length - 1]
      this.valToIndex.set(lastEl, idx);
      // 交换元素
      [this.arr[idx], this.arr[this.arr.length - 1]] = [this.arr[this.arr.length - 1], this.arr[idx]];
      // 删除元素
      this.arr.pop();
      this.valToIndex.delete(val)
      return true
  }

  getRandom() {
      return this.arr[this._rand()]
  }

  _rand() {
      return Math.floor(Math.random() * this.arr.length)
  }
}

/** 
* Your RandomizedSet object will be instantiated and called as such:
* var obj = new RandomizedSet()
* var param_1 = obj.insert(val)
* var param_2 = obj.remove(val)
* var param_3 = obj.getRandom()
*/

const randomizedSet = new RandomizedSet();
console.log(randomizedSet.insert(1))    // 向集合中插入 1 。返回 true 表示 1 被成功地插入。
console.log(randomizedSet.remove(2))    // 返回 false ，表示集合中不存在 2 。
console.log(randomizedSet.insert(2))    // 向集合中插入 2 。返回 true 。集合现在包含 [1,2] 。
console.log(randomizedSet.getRandom())// getRandom 应随机返回 1 或 2 。
console.log(randomizedSet.remove(1))    // 从集合中移除 1 ，返回 true 。集合现在包含 [2] 。
console.log(randomizedSet.insert(2))    // 2 已在集合中，所以返回 false 。
console.log(randomizedSet.getRandom())  // 由于 2 是集合中唯一的数字，getRandom 总是返回 2 。